React ๋ ๋๋ง ํ๋ก์ธ์ค ์ฌ์ธต ๋ถ์: ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ, ์ต์ ํ ๊ธฐ๋ฒ, ๊ทธ๋ฆฌ๊ณ ๊ณ ์ฑ๋ฅ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ํ๊ตฌํฉ๋๋ค.
React ๋ ๋๋ง: ์ปดํฌ๋ํธ ๋ ๋๋ง๊ณผ ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ
์ฌ์ฉ์ ์ธํฐํ์ด์ค ๊ตฌ์ถ์ ์ํ ์ธ๊ธฐ ์๋ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ React๋ ํจ์จ์ ์ธ ๋ ๋๋ง ํ๋ก์ธ์ค๋ฅผ ํตํด ์ปดํฌ๋ํธ๋ฅผ ํ์ํ๊ณ ์ ๋ฐ์ดํธํฉ๋๋ค. React๊ฐ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ณ , ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ฉฐ, ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ ๊ฒฌ๊ณ ํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ์ด๋ฌํ ๊ฐ๋ ๋ค์ ์์ธํ ํ๊ตฌํ๋ฉฐ, ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ ์ํ ์ค์ฉ์ ์ธ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
React ๋ ๋๋ง ํ๋ก์ธ์ค ์ดํดํ๊ธฐ
React ์๋์ ํต์ฌ์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ์ ๊ฐ์ DOM(Virtual DOM)์ ์์ต๋๋ค. ์ปดํฌ๋ํธ์ state๋ props๊ฐ ๋ณ๊ฒฝ๋ ๋, React๋ ์ค์ DOM์ ์ง์ ์กฐ์ํ์ง ์์ต๋๋ค. ๋์ , ๊ฐ์ DOM์ด๋ผ๊ณ ๋ถ๋ฆฌ๋ DOM์ ๊ฐ์ ํํ์ ์์ฑํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์, React๋ ์ด ๊ฐ์ DOM์ ์ด์ ๋ฒ์ ๊ณผ ๋น๊ตํ์ฌ ์ค์ DOM์ ์ ๋ฐ์ดํธํ๋ ๋ฐ ํ์ํ ์ต์ํ์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ณํฉ๋๋ค. ์ด ํ๋ก์ธ์ค๋ ์ฌ์กฐ์ (reconciliation)์ด๋ผ๊ณ ์๋ ค์ ธ ์์ผ๋ฉฐ, ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํต๋๋ค.
๊ฐ์ DOM๊ณผ ์ฌ์กฐ์ (Reconciliation)
๊ฐ์ DOM์ ์ค์ DOM์ ๊ฐ๋ฒผ์ด ์ธ-๋ฉ๋ชจ๋ฆฌ ํํ์ ๋๋ค. ์ค์ DOM๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ์กฐ์ํ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋๋ฉด React๋ ์๋ก์ด ๊ฐ์ DOM ํธ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ์ด์ ํธ๋ฆฌ์ ๋น๊ตํฉ๋๋ค. ์ด ๋น๊ต๋ฅผ ํตํด React๋ ์ค์ DOM์์ ์ด๋ค ํน์ ๋ ธ๋๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํ๋์ง ๊ฒฐ์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ React๋ ์ด๋ฌํ ์ต์ํ์ ์ ๋ฐ์ดํธ๋ฅผ ์ค์ DOM์ ์ ์ฉํ์ฌ ๋ ๋น ๋ฅด๊ณ ์ฑ๋ฅ์ด ์ข์ ๋ ๋๋ง ํ๋ก์ธ์ค๋ฅผ ๊ตฌํํฉ๋๋ค.
๋ค์์ ๊ฐ๋จํ ์์์ ๋๋ค:
์๋๋ฆฌ์ค: ๋ฒํผ ํด๋ฆญ์ผ๋ก ํ๋ฉด์ ํ์๋ ์นด์ดํฐ๊ฐ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
React ๋ฏธ์ฌ์ฉ ์: ๊ฐ ํด๋ฆญ์ ์ ์ฒด DOM ์ ๋ฐ์ดํธ๋ฅผ ์ ๋ฐํ์ฌ ์ ์ฒด ํ์ด์ง ๋๋ ํ์ด์ง์ ๋์ ๋ถ๋ถ์ ๋ค์ ๋ ๋๋งํ๊ฒ ๋์ด ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
React ์ฌ์ฉ ์: ๊ฐ์ DOM ๋ด์ ์นด์ดํฐ ๊ฐ๋ง ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ฌ์กฐ์ ํ๋ก์ธ์ค๋ ์ด ๋ณ๊ฒฝ ์ฌํญ์ ์๋ณํ๊ณ ์ค์ DOM์ ํด๋น ๋ ธ๋์๋ง ์ ์ฉํฉ๋๋ค. ํ์ด์ง์ ๋๋จธ์ง ๋ถ๋ถ์ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฏ๋ก ๋ถ๋๋ฝ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
React๊ฐ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ: ๋น๊ต ์๊ณ ๋ฆฌ์ฆ(Diffing Algorithm)
React์ ๋น๊ต ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์กฐ์ ํ๋ก์ธ์ค์ ํต์ฌ์ ๋๋ค. ์๋ก์ด ๊ฐ์ DOM ํธ๋ฆฌ์ ์ด์ ํธ๋ฆฌ๋ฅผ ๋น๊ตํ์ฌ ์ฐจ์ด์ ์ ์๋ณํฉ๋๋ค. ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋น๊ต๋ฅผ ์ต์ ํํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ๊ฐ์ ์ ํฉ๋๋ค:
- ๋ค๋ฅธ ํ์ ์ ๋ ์๋ฆฌ๋จผํธ๋ ๋ค๋ฅธ ํธ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. ๋ฃจํธ ์๋ฆฌ๋จผํธ์ ํ์ ์ด ๋ค๋ฅธ ๊ฒฝ์ฐ(์: <div>๋ฅผ <span>์ผ๋ก ๋ณ๊ฒฝ), React๋ ์ด์ ํธ๋ฆฌ๋ฅผ ํด์ (unmount)ํ๊ณ ์๋ก์ด ํธ๋ฆฌ๋ฅผ ์ฒ์๋ถํฐ ๋ค์ ๊ตฌ์ถํฉ๋๋ค.
- ๊ฐ์ ํ์ ์ ๋ ์๋ฆฌ๋จผํธ๋ฅผ ๋น๊ตํ ๋, React๋ ์์ฑ์ ๋ณด๊ณ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ง ํ๋จํฉ๋๋ค. ์์ฑ๋ง ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ, React๋ ๊ธฐ์กด DOM ๋ ธ๋์ ์์ฑ๋ง ์ ๋ฐ์ดํธํฉ๋๋ค.
- React๋ ๋ฆฌ์คํธ ์์ดํ ์ ๊ณ ์ ํ๊ฒ ์๋ณํ๊ธฐ ์ํด key prop์ ์ฌ์ฉํฉ๋๋ค. key prop์ ์ ๊ณตํ๋ฉด React๊ฐ ์ ์ฒด ๋ฆฌ์คํธ๋ฅผ ๋ค์ ๋ ๋๋งํ์ง ์๊ณ ๋ ํจ์จ์ ์ผ๋ก ๋ฆฌ์คํธ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๊ฐ์ ์ ์ดํดํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ ํจ์จ์ ์ธ React ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฆฌ์คํธ๋ฅผ ๋ ๋๋งํ ๋ key๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ฑ๋ฅ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
React ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ(Lifecycle)
React ์ปดํฌ๋ํธ๋ ์ ์ ์๋ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ด๋ ์ปดํฌ๋ํธ์ ์กด์ฌ ๊ธฐ๊ฐ ์ค ํน์ ์์ ์ ํธ์ถ๋๋ ์ผ๋ จ์ ๋ฉ์๋๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด๋ฌํ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์ดํดํ๋ฉด ๊ฐ๋ฐ์๊ฐ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง, ์ ๋ฐ์ดํธ, ๋ง์ดํธ ํด์ ๋๋ ๋ฐฉ์์ ์ ์ดํ ์ ์์ต๋๋ค. ํ (Hooks)์ด ๋์ ๋ ํ์๋ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ ์ฌ์ ํ ์ ํจํ๋ฉฐ, ๊ทธ ๊ธฐ๋ณธ ์๋ฆฌ๋ฅผ ์ดํดํ๋ ๊ฒ์ ์ ์ตํฉ๋๋ค.
ํด๋์ค ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋
ํด๋์ค ๊ธฐ๋ฐ ์ปดํฌ๋ํธ์์๋ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ ์์ ์ ์ฌ๋ฌ ๋จ๊ณ์์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. ์ฃผ์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
constructor(props): ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๊ธฐ ์ ์ ํธ์ถ๋ฉ๋๋ค. state๋ฅผ ์ด๊ธฐํํ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.static getDerivedStateFromProps(props, state): ์ด๊ธฐ ๋ง์ดํธ ๋ฐ ํ์ ์ ๋ฐ์ดํธ ์ ๋ ๋๋ง ์ ์ ํธ์ถ๋ฉ๋๋ค. state๋ฅผ ์ ๋ฐ์ดํธํ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ฑฐ๋, ์๋ก์ด props๊ฐ state ์ ๋ฐ์ดํธ๋ฅผ ํ์๋ก ํ์ง ์์์ ๋ํ๋ด๊ธฐ ์ํดnull์ ๋ฐํํด์ผ ํฉ๋๋ค. ์ด ๋ฉ์๋๋ props ๋ณ๊ฒฝ์ ๊ธฐ๋ฐํ ์์ธก ๊ฐ๋ฅํ state ์ ๋ฐ์ดํธ๋ฅผ ์ด์งํฉ๋๋ค.render(): ๋ ๋๋งํ JSX๋ฅผ ๋ฐํํ๋ ํ์ ๋ฉ์๋์ ๋๋ค. props์ state์ ์์ ํจ์์ฌ์ผ ํฉ๋๋ค.componentDidMount(): ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋(ํธ๋ฆฌ์ ์ฝ์ ๋) ์งํ์ ํธ์ถ๋ฉ๋๋ค. ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ ๊ตฌ๋ ์ค์ ๊ณผ ๊ฐ์ ๋ถ์ ํจ๊ณผ(side effects)๋ฅผ ์ํํ๊ธฐ์ ์ข์ ์์น์ ๋๋ค.shouldComponentUpdate(nextProps, nextState): ์๋ก์ด props๋ state๋ฅผ ๋ฐ์ ๋ ๋ ๋๋ง ์ ์ ํธ์ถ๋ฉ๋๋ค. ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ์ฌ ์ฑ๋ฅ์ ์ต์ ํํ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋์ด์ผ ํ๋ฉดtrue๋ฅผ, ๊ทธ๋ ์ง ์์ผ๋ฉดfalse๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.getSnapshotBeforeUpdate(prevProps, prevState): DOM์ด ์ ๋ฐ์ดํธ๋๊ธฐ ์ง์ ์ ํธ์ถ๋ฉ๋๋ค. ๋ณ๊ฒฝ๋๊ธฐ ์ ์ DOM ์ ๋ณด(์: ์คํฌ๋กค ์์น)๋ฅผ ์บก์ฒํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ๋ฐํ ๊ฐ์componentDidUpdate()์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ฉ๋๋ค.componentDidUpdate(prevProps, prevState, snapshot): ์ ๋ฐ์ดํธ๊ฐ ๋ฐ์ํ ์งํ์ ํธ์ถ๋ฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋ ํ DOM ์์ ์ ์ํํ๊ธฐ์ ์ข์ ์์น์ ๋๋ค.componentWillUnmount(): ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ํด์ ๋๊ณ ํ๊ดด๋๊ธฐ ์ง์ ์ ํธ์ถ๋ฉ๋๋ค. ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ ๋๋ ๋คํธ์ํฌ ์์ฒญ ์ทจ์์ ๊ฐ์ ๋ฆฌ์์ค ์ ๋ฆฌ ์์ ์ ํ๊ธฐ์ ์ข์ ์์น์ ๋๋ค.static getDerivedStateFromError(error): ๋ ๋๋ง ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ๋ฅผ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ state๋ฅผ ์ ๋ฐ์ดํธํ ๊ฐ์ ๋ฐํํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ๋ ๋์ฒด UI(fallback UI)๋ฅผ ํ์ํ ์ ์์ต๋๋ค.componentDidCatch(error, info): ์์ ์ปดํฌ๋ํธ์์ ๋ ๋๋ง ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ์ ์ปดํฌ๋ํธ ์คํ ์ ๋ณด๋ฅผ ์ธ์๋ก ๋ฐ์ต๋๋ค. ์ค๋ฅ ๋ณด๊ณ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ธฐ์ ์ข์ ์์น์ ๋๋ค.
์๋ช ์ฃผ๊ธฐ ๋ฉ์๋ ์ค์ ์ฌ์ฉ ์์
๋ง์ดํธ๋ ๋ API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ props๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ ์ปดํฌ๋ํธ๋ฅผ ์๊ฐํด ๋ณด์ธ์:
class DataFetcher extends React.Component {
constructor(props) {
super(props);
this.state = { data: null };
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps) {
if (this.props.url !== prevProps.url) {
this.fetchData();
}
}
fetchData = async () => {
try {
const response = await fetch(this.props.url);
const data = await response.json();
this.setState({ data });
} catch (error) {
console.error('๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์ค๋ฅ:', error);
}
};
render() {
if (!this.state.data) {
return <p>๋ก๋ฉ ์ค...</p>;
}
return <div>{this.state.data.message}</div>;
}
}
์ด ์์ ์์:
componentDidMount()๋ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ง์ดํธ๋ ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.componentDidUpdate()๋urlprop์ด ๋ณ๊ฒฝ๋๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ต๋๋ค.render()๋ฉ์๋๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ , ๋ฐ์ดํฐ๊ฐ ์ค๋น๋๋ฉด ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
์๋ช ์ฃผ๊ธฐ ๋ฉ์๋์ ์ค๋ฅ ์ฒ๋ฆฌ
React๋ ๋ ๋๋ง ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ ์ ๊ณตํฉ๋๋ค:
static getDerivedStateFromError(error): ๋ ๋๋ง ์ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ๋ฅผ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ state๋ฅผ ์ ๋ฐ์ดํธํ ๊ฐ์ ๋ฐํํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ๋ ๋์ฒด UI๋ฅผ ํ์ํ ์ ์์ต๋๋ค.componentDidCatch(error, info): ์์ ์ปดํฌ๋ํธ์์ ๋ ๋๋ง ์ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ์ค๋ฅ์ ์ปดํฌ๋ํธ ์คํ ์ ๋ณด๋ฅผ ์ธ์๋ก ๋ฐ์ต๋๋ค. ์ค๋ฅ ๋ณด๊ณ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ธฐ์ ์ข์ ์์น์ ๋๋ค.
์ด๋ฌํ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ค๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, getDerivedStateFromError()๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ componentDidCatch()๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
ํ (Hooks)๊ณผ ํจ์ํ ์ปดํฌ๋ํธ
React 16.8์ ๋์ ๋ React ํ ์ ํจ์ํ ์ปดํฌ๋ํธ์์ state ๋ฐ ๊ธฐํ React ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ํจ์ํ ์ปดํฌ๋ํธ๋ ํด๋์ค ์ปดํฌ๋ํธ์ ๊ฐ์ ๋ฐฉ์์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์ง๋ง, ํ ์ ๊ทธ์ ์์ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
useState(): ํจ์ํ ์ปดํฌ๋ํธ์ state๋ฅผ ์ถ๊ฐํ ์ ์๊ฒ ํด์ค๋๋ค.useEffect():componentDidMount(),componentDidUpdate(),componentWillUnmount()์ ์ ์ฌํ๊ฒ ํจ์ํ ์ปดํฌ๋ํธ์์ ๋ถ์ ํจ๊ณผ๋ฅผ ์ํํ ์ ์๊ฒ ํด์ค๋๋ค.useContext(): React ์ปจํ ์คํธ์ ์ ๊ทผํ ์ ์๊ฒ ํด์ค๋๋ค.useReducer(): ๋ฆฌ๋์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ณต์กํ state๋ฅผ ๊ด๋ฆฌํ ์ ์๊ฒ ํด์ค๋๋ค.useCallback(): ์์กด์ฑ ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋์์ ๋๋ง ๋ณ๊ฒฝ๋๋ ํจ์์ ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๋ฒ์ ์ ๋ฐํํฉ๋๋ค.useMemo(): ์์กด์ฑ ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋์์ ๋๋ง ๋ค์ ๊ณ์ฐ๋๋ ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๊ฐ์ ๋ฐํํฉ๋๋ค.useRef(): ๋ ๋๋ง ๊ฐ์ ๊ฐ์ ์ ์งํ ์ ์๊ฒ ํด์ค๋๋ค.useImperativeHandle():ref๋ฅผ ์ฌ์ฉํ ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ๋ ธ์ถ๋๋ ์ธ์คํด์ค ๊ฐ์ ์ฌ์ฉ์ ์ ์ํฉ๋๋ค.useLayoutEffect(): ๋ชจ๋ DOM ๋ณ๊ฒฝ ํ์ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋useEffect์ ๋ฒ์ ์ ๋๋ค.useDebugValue(): React DevTools์์ ์ฌ์ฉ์ ์ ์ ํ ์ ๋ํ ๊ฐ์ ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
useEffect ํ ์์
๋ค์์ useEffect() ํ
์ ์ฌ์ฉํ์ฌ ํจ์ํ ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์
๋๋ค:
import React, { useState, useEffect } from 'react';
function DataFetcher({ url }) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
const json = await response.json();
setData(json);
} catch (error) {
console.error('๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์ค๋ฅ:', error);
}
}
fetchData();
}, [url]); // URL์ด ๋ณ๊ฒฝ๋ ๋๋ง effect๋ฅผ ๋ค์ ์คํํฉ๋๋ค
if (!data) {
return <p>๋ก๋ฉ ์ค...</p>;
}
return <div>{data.message}</div>;
}
์ด ์์ ์์:
useEffect()๋ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ ๋๋ง๋ ๋์urlprop์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.useEffect()์ ๋ ๋ฒ์งธ ์ธ์๋ ์์กด์ฑ ๋ฐฐ์ด์ ๋๋ค. ์์กด์ฑ ์ค ํ๋๋ผ๋ ๋ณ๊ฒฝ๋๋ฉด effect๊ฐ ๋ค์ ์คํ๋ฉ๋๋ค.useState()ํ ์ ์ปดํฌ๋ํธ์ state๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
React ๋ ๋๋ง ์ฑ๋ฅ ์ต์ ํ
ํจ์จ์ ์ธ ๋ ๋๋ง์ ๊ณ ์ฑ๋ฅ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์์ ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๊ธฐ๋ฒ์ ๋๋ค:
1. ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์งํ๊ธฐ
๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํํ๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ๊ฒ์ ๋๋ค. ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๊ธฐ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
React.memo()์ฌ์ฉ:React.memo()๋ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ์ ๋๋ค. props๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋งํฉ๋๋ค.shouldComponentUpdate()๊ตฌํ: ํด๋์ค ์ปดํฌ๋ํธ์์๋shouldComponentUpdate()์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ props๋ state ๋ณ๊ฒฝ์ ๋ฐ๋ฅธ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.useMemo()์useCallback()์ฌ์ฉ: ์ด ํ ๋ค์ ๊ฐ๊ณผ ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ ํ์ฌ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.- ๋ถ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ฌ์ฉ: ๋ถ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์์ ํ๋ ๋์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋ ์ฝ๊ฒ ๊ฐ์งํ๊ณ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
2. ์ฝ๋ ๋ถํ (Code-Splitting)
์ฝ๋ ๋ถํ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ์์ ์ฒญํฌ๋ก ๋๋์ด ํ์ํ ๋ ๋ก๋ํ๋ ํ๋ก์ธ์ค์ ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๊ธฐ ๋ก๋ ์๊ฐ์ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
React๋ ์ฝ๋ ๋ถํ ์ ๊ตฌํํ๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค:
React.lazy()์Suspense์ฌ์ฉ: ์ด ๊ธฐ๋ฅ๋ค์ ์ฌ์ฉํ๋ฉด ์ปดํฌ๋ํธ๋ฅผ ๋์ ์ผ๋ก ์ํฌํธํ์ฌ ํ์ํ ๋๋ง ๋ก๋ํ ์ ์์ต๋๋ค.- ๋์ ์ํฌํธ(dynamic imports) ์ฌ์ฉ: ๋์ ์ํฌํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ํ์์ ๋ฐ๋ผ ๋ก๋ํ ์ ์์ต๋๋ค.
3. ๋ฆฌ์คํธ ๊ฐ์ํ(List Virtualization)
ํฐ ๋ฆฌ์คํธ๋ฅผ ๋ ๋๋งํ ๋ ๋ชจ๋ ํญ๋ชฉ์ ํ ๋ฒ์ ๋ ๋๋งํ๋ ๊ฒ์ ๋๋ฆด ์ ์์ต๋๋ค. ๋ฆฌ์คํธ ๊ฐ์ํ ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ฉด ํ์ฌ ํ๋ฉด์ ๋ณด์ด๋ ํญ๋ชฉ๋ง ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์คํฌ๋กคํ๋ฉด ์๋ก์ด ํญ๋ชฉ์ด ๋ ๋๋ง๋๊ณ ์ค๋๋ ํญ๋ชฉ์ ๋ง์ดํธ ํด์ ๋ฉ๋๋ค.
๋ฆฌ์คํธ ๊ฐ์ํ ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํ๋ ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
react-windowreact-virtualized
4. ์ด๋ฏธ์ง ์ต์ ํ
์ด๋ฏธ์ง๋ ์ข ์ข ์ฑ๋ฅ ๋ฌธ์ ์ ์ค์ํ ์์ธ์ด ๋ ์ ์์ต๋๋ค. ๋ค์์ ์ด๋ฏธ์ง ์ต์ ํ๋ฅผ ์ํ ๋ช ๊ฐ์ง ํ์ ๋๋ค:
- ์ต์ ํ๋ ์ด๋ฏธ์ง ํ์ ์ฌ์ฉ: ๋ ๋์ ์์ถ๋ฅ ๊ณผ ํ์ง์ ์ํด WebP์ ๊ฐ์ ํ์์ ์ฌ์ฉํ์ธ์.
- ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง: ํ์ ํฌ๊ธฐ์ ๋ง๋ ์ ์ ํ ์น์๋ก ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ์ธ์.
- ์ด๋ฏธ์ง ์ง์ฐ ๋ก๋ฉ(Lazy load): ํ๋ฉด์ ๋ณด์ผ ๋๋ง ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ์ธ์.
- CDN ์ฌ์ฉ: ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ(CDN)๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์ง๋ฆฌ์ ์ผ๋ก ๋ ๊ฐ๊น์ด ์๋ฒ์์ ์ด๋ฏธ์ง๋ฅผ ์ ๊ณตํ์ธ์.
5. ํ๋กํ์ผ๋ง ๋ฐ ๋๋ฒ๊น
React๋ ๋ ๋๋ง ์ฑ๋ฅ์ ํ๋กํ์ผ๋งํ๊ณ ๋๋ฒ๊น ํ๊ธฐ ์ํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. React Profiler๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๋๋ง ์ฑ๋ฅ์ ๊ธฐ๋กํ๊ณ ๋ถ์ํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ผ์ผํค๋ ์ปดํฌ๋ํธ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค.
React DevTools ๋ธ๋ผ์ฐ์ ํ์ฅ ํ๋ก๊ทธ๋จ์ React ์ปดํฌ๋ํธ, state, props๋ฅผ ๊ฒ์ฌํ๊ธฐ ์ํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก
์์ : ํจ์ํ ์ปดํฌ๋ํธ ๋ฉ๋ชจ์ด์ ์ด์ ํ๊ธฐ
์ฌ์ฉ์ ์ด๋ฆ์ ํ์ํ๋ ๊ฐ๋จํ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ์๊ฐํด ๋ณด์ธ์:
function UserProfile({ user }) {
console.log('UserProfile ๋ ๋๋ง ์ค');
return <div>{user.name}</div>;
}
์ด ์ปดํฌ๋ํธ๊ฐ ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ค๋ฉด React.memo()๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
import React from 'react';
const UserProfile = React.memo(({ user }) => {
console.log('UserProfile ๋ ๋๋ง ์ค');
return <div>{user.name}</div>;
});
์ด์ UserProfile์ user prop์ด ๋ณ๊ฒฝ๋ ๋๋ง ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
์์ : useCallback() ์ฌ์ฉํ๊ธฐ
์์ ์ปดํฌ๋ํธ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ๋ฌํ๋ ์ปดํฌ๋ํธ๋ฅผ ์๊ฐํด ๋ณด์ธ์:
import React, { useState } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<ChildComponent onClick={handleClick} />
<p>์นด์ดํธ: {count}</p>
</div>
);
}
function ChildComponent({ onClick }) {
console.log('ChildComponent ๋ ๋๋ง ์ค');
return <button onClick={onClick}>ํด๋ฆญํ์ธ์</button>;
}
์ด ์์ ์์ handleClick ํจ์๋ ParentComponent๊ฐ ๋ ๋๋ง๋ ๋๋ง๋ค ์๋ก ์์ฑ๋ฉ๋๋ค. ์ด๋ก ์ธํด ChildComponent๋ props๊ฐ ๋ณ๊ฒฝ๋์ง ์์์์๋ ๋ถ๊ตฌํ๊ณ ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด useCallback()์ ์ฌ์ฉํ์ฌ handleClick ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
ํ ์ ์์ต๋๋ค:
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]); // count๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ํจ์๋ฅผ ์ฌ์์ฑํฉ๋๋ค
return (
<div>
<ChildComponent onClick={handleClick} />
<p>์นด์ดํธ: {count}</p>
</div>
);
}
function ChildComponent({ onClick }) {
console.log('ChildComponent ๋ ๋๋ง ์ค');
return <button onClick={onClick}>ํด๋ฆญํ์ธ์</button>;
}
์ด์ handleClick ํจ์๋ count state๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ์ฌ์์ฑ๋ฉ๋๋ค.
์์ : useMemo() ์ฌ์ฉํ๊ธฐ
props๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์๋ ๊ฐ์ ๊ณ์ฐํ๋ ์ปดํฌ๋ํธ๋ฅผ ์๊ฐํด ๋ณด์ธ์:
import React, { useState } from 'react';
function MyComponent({ items }) {
const [filter, setFilter] = useState('');
const filteredItems = items.filter(item => item.name.includes(filter));
return (
<div>
<input type="text" value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{filteredItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
์ด ์์ ์์ filteredItems ๋ฐฐ์ด์ items prop์ด ๋ณ๊ฒฝ๋์ง ์์์์๋ ๋ถ๊ตฌํ๊ณ MyComponent๊ฐ ๋ ๋๋ง๋ ๋๋ง๋ค ๋ค์ ๊ณ์ฐ๋ฉ๋๋ค. ์ด๋ items ๋ฐฐ์ด์ด ํด ๊ฒฝ์ฐ ๋นํจ์จ์ ์ผ ์ ์์ต๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด useMemo()๋ฅผ ์ฌ์ฉํ์ฌ filteredItems ๋ฐฐ์ด์ ๋ฉ๋ชจ์ด์ ์ด์
ํ ์ ์์ต๋๋ค:
import React, { useState, useMemo } from 'react';
function MyComponent({ items }) {
const [filter, setFilter] = useState('');
const filteredItems = useMemo(() => {
return items.filter(item => item.name.includes(filter));
}, [items, filter]); // items ๋๋ filter๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ๋ค์ ๊ณ์ฐํฉ๋๋ค
return (
<div>
<input type="text" value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{filteredItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
์ด์ filteredItems ๋ฐฐ์ด์ items prop์ด๋ filter state๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ๋ค์ ๊ณ์ฐ๋ฉ๋๋ค.
๊ฒฐ๋ก
React์ ๋ ๋๋ง ํ๋ก์ธ์ค์ ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ดํดํ๋ ๊ฒ์ ์ฑ๋ฅ์ด ์ข๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํ์์ ์ ๋๋ค. ๊ฐ๋ฐ์๋ ๋ฉ๋ชจ์ด์ ์ด์ , ์ฝ๋ ๋ถํ , ๋ฆฌ์คํธ ๊ฐ์ํ์ ๊ฐ์ ๊ธฐ๋ฒ์ ํ์ฉํ์ฌ ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋ถ๋๋ฝ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋ค ์ ์์ต๋๋ค. ํ ์ ๋์ ์ผ๋ก ํจ์ํ ์ปดํฌ๋ํธ์์ state์ ๋ถ์ ํจ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ ๊ฐ๋จํด์ก์ผ๋ฉฐ, ์ด๋ React ๊ฐ๋ฐ์ ์ ์ฐ์ฑ๊ณผ ๊ฐ๋ ฅํจ์ ๋์ฑ ํฅ์์์ผฐ์ต๋๋ค. ์์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ ์์คํ ์ ๊ตฌ์ถํ๋ , React์ ๋ ๋๋ง ๊ฐ๋ ์ ๋ง์คํฐํ๋ ๊ฒ์ ๊ณ ํ์ง ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋๋ ๋ฅ๋ ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ๊ฒ์ ๋๋ค.